package br.com.petsis.utilitarios;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Locale;

public class UtilDate {

	private static final Locale locale = new Locale("pt", "BR");

	public static final String FORMATO_DATA_PADRAO = "dd/MM/yyyy";
	public static final String FORMATO_HORA_PADRAO = "HH:mm";

	public static String getDataComoString(Date data, String formatoData) {
		if (data == null) {
			return "";
		}
		SimpleDateFormat dataFormat = new SimpleDateFormat(formatoData, locale);
		return dataFormat.format(data);
	}
	
	public static String getHoraComoString(Date data) {
		if (data == null) {
			return "";
		}
		SimpleDateFormat dataFormat = new SimpleDateFormat(FORMATO_HORA_PADRAO, locale);
		return dataFormat.format(data);
	}
	
	public static Integer getHora(Date data){
		Calendar hora = Calendar.getInstance();
		hora.setTime(data);
		return hora.get(Calendar.HOUR_OF_DAY);
	}
	
	public static Integer getMinuto(Date data){
		Calendar hora = Calendar.getInstance();
		hora.setTime(data);
		return hora.get(Calendar.MINUTE);
	}

	public static String getAnoAtual() {
		return getAno(getDataAtual());
	}

	public static Date getDataAtual() {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(new Date());
		calendar.clear(Calendar.HOUR);
		calendar.clear(Calendar.HOUR_OF_DAY);
		calendar.clear(Calendar.MINUTE);
		calendar.clear(Calendar.SECOND);
		calendar.clear(Calendar.MILLISECOND);
		calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
		return calendar.getTime();
	}

	public static String getAno(Date data) {
		if (data == null) {
			return "";
		}
		return getDataComoString(data, "yyyy");
	}

	public static int getAnoInt(Date data) {
		return Integer.parseInt(getAno(data));
	}

	public static int getMesInt(Date data) {
		String mes = getDataComoString(data, "MM");
		return Integer.parseInt(mes);
	}
	
	public static String getMesString(Date data) {
		return getDataComoString(data, "MMMM");
	}
	
	public static Integer getDiaInt(Date data){
		String dia = getDataComoString(data, "dd");
		return Integer.parseInt(dia);
	}
	
	public static String getDiaString(Date data){
		GregorianCalendar calendar = new GregorianCalendar();
		calendar.setTime(data);
		String[] diaSemana = new String[]{"Domingo","Segunda",
		"Terça","Quarta","Quinta","Sexta","Sábado"};
		return diaSemana[calendar.get(GregorianCalendar.DAY_OF_WEEK)-1];
	}
	
	public static Integer getDiaDaSemanaInt(Date data){
		GregorianCalendar calendar = new GregorianCalendar();
		calendar.setTime(data);
		return calendar.get(GregorianCalendar.DAY_OF_WEEK);
	}

	public static int diferencaEmDias(Date dataA, Date dataB) {
		int diferencaTemporaria = 0;
		int diferencaEmDias = 0;
		Calendar menorData = Calendar.getInstance();
		Calendar maiorData = Calendar.getInstance();
		if (dataA.compareTo(dataB) < 0) {
			menorData.setTime(dataA);
			maiorData.setTime(dataB);
		} else {
			menorData.setTime(dataB);
			maiorData.setTime(dataA);
		}
		while (menorData.get(Calendar.YEAR) != maiorData.get(Calendar.YEAR)) {
			diferencaTemporaria = 365 * (maiorData.get(Calendar.YEAR) - menorData
					.get(Calendar.YEAR));
			diferencaEmDias += diferencaTemporaria;
			menorData.add(Calendar.DAY_OF_YEAR, diferencaTemporaria);
		}
		if (menorData.get(Calendar.DAY_OF_YEAR) != maiorData
				.get(Calendar.DAY_OF_YEAR)) {
			diferencaTemporaria = maiorData.get(Calendar.DAY_OF_YEAR)
					- menorData.get(Calendar.DAY_OF_YEAR);
			diferencaEmDias += diferencaTemporaria;
			menorData.add(Calendar.DAY_OF_YEAR, diferencaTemporaria);
		}
		return diferencaEmDias;
	}

	public static int diferencaEmAnos(Date dataA, Date dataB) {
		return (getAnoInt(dataA) - getAnoInt(dataB));
	}

	public static int diferencaEmMeses(Date dataA, Date dataB) {
		int anoA = getAnoInt(dataA);
		int anoB = getAnoInt(dataB);
		int mesA = getMesInt(dataA);
		int mesB = getMesInt(dataB);
		if (dataA.before(dataB)) {
			return ((anoB - anoA) * 12 + (mesB - mesA)) * -1;
		} else {
			return (anoA - anoB) * 12 + (mesA - mesB);
		}
	}

	public static Date getData(String dataString, String formatoDaData)
			throws ParseException {
		SimpleDateFormat dateFormat = new SimpleDateFormat(formatoDaData);
		dateFormat.setLenient(false);
		return dateFormat.parse(dataString);
	}

	public static Date getData(String dataString) throws ParseException {
		return getData(dataString, "dd/MM/yyyy");
	}

	public static Boolean data1MenorQueData2(Date data1, Date data2) {
		if (data1 == null || data2 == null) {
			return null;
		}
		return data1.before(data2);
	}

	public static Boolean data1MenorOuIgualQueData2(Date data1, Date data2){ 
    	if(data1 == null || data2 == null){
    		return null;
    	}
    	if(data1.before(data2) || data1.equals(data2)){
    		return true;
    	}else{
    		return false;
    	}
    }
	
	public static List<Date> recuperaDiasDoMesAno(Date data){
		List<Date> dias = new ArrayList<Date>();
		Calendar cal = Calendar.getInstance(); 
		cal.setTime (data);
		int ultimoDia = cal.getActualMaximum (Calendar.DAY_OF_MONTH);
		for(int i = 1; i <= ultimoDia; i++){
			Calendar dia = Calendar.getInstance();
			dia.set(getAnoInt(data), getMesInt(data)-1, i);
			dias.add(dia.getTime());
		}
		return dias;
	}
	
	public static boolean data1IgualData2(Date data1, Date data2){
		return getDataComoString(data1, FORMATO_DATA_PADRAO)
			.equals(getDataComoString(data2, FORMATO_DATA_PADRAO));
	}
	
	public static Date getDataAcrescidaEmDias(Date data, Integer dias){
		Calendar retorno = Calendar.getInstance();
		retorno.setTime(data);
		retorno.add(Calendar.DAY_OF_MONTH, dias);
		return retorno.getTime();
	}
	
	public static Date getDataAcrescidaEmHoras(Date data, Integer horas){
		Calendar retorno = Calendar.getInstance();
		retorno.setTime(data);
		retorno.add(Calendar.HOUR_OF_DAY, horas);
		return retorno.getTime();
	}
	
	public static Date getDataAcrescidaEmMinutos(Date data, Integer minutos){
		Calendar retorno = Calendar.getInstance();
		retorno.setTime(data);
		retorno.add(Calendar.MINUTE, minutos);
		return retorno.getTime();
	}

}
